using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using Charisma.Linq;

namespace Charisma.MongoDb.Linq.Expressions
{
  internal sealed class ProjectionExpression : MongoExpression
  {
    public QueryExpression Query { get; private set; }
    public Expression Projector { get; private set; }
    public LambdaExpression Aggregator { get; private set; }
    public ResultType ResultType { get; private set; }

    [ContractInvariantMethod]
    private void ObjectInvariant()
    {
      Contract.Invariant(Projector != null);
      Contract.Invariant(Query != null);
    }

    public ProjectionExpression(QueryExpression query, Expression projector, LambdaExpression aggregator, ResultType resultType)
      : base(MongoExpressionType.Projection, aggregator != null ? aggregator.Body.Type : typeof(IEnumerable<>).MakeGenericType(projector.Type))
    {
      Contract.Requires(query != null);
      Contract.Requires(projector != null);

      Projector = projector;
      Aggregator = aggregator;
      Query = query;
      ResultType = resultType;
    }
  }
}